package com.raj.sample;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

import org.snmp4j.CommunityTarget;
import org.snmp4j.MessageDispatcher;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

public class SNMPSender {
	private ConcurrentHashMap<String, HashMap<String, String>> result = new ConcurrentHashMap<String, HashMap<String, String>>();
	private Snmp snmp;
	MessageDispatcher dispatcher;
	private String threadPoolName = "default";
	private int threadPoolSize = 10;

	public SNMPSender(String threadPoolName, int threadPoolSize) throws IOException {
		this.threadPoolName = threadPoolName;
		this.threadPoolSize = threadPoolSize;
		dispatcher = new MultiThreadedMessageDispatcher(ThreadPool.create(threadPoolName, threadPoolSize), new MessageDispatcherImpl());
		snmp = new Snmp(dispatcher, new DefaultUdpTransportMapping());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
		snmp.listen();
	}

	public ConcurrentHashMap<String, HashMap<String, String>> getResult() throws IOException {
		// ((MultiThreadedMessageDispatcher) dispatcher).stop();

		snmp.close();
		return result;
	}

	public void send(String ip, String community, String mibStr) throws IOException {
		SNMPReceiver listener = new SNMPReceiver(this);
		listener.setKey(ip + mibStr);
		CommunityTarget target = new CommunityTarget();
		target.setVersion(SnmpConstants.version1);
		target.setCommunity(new OctetString(community));
		target.setAddress(new UdpAddress(ip + "/161"));
		PDU pdu = new PDU();
//		pdu.setRequestID(this.hashCode());
		pdu.add(new VariableBinding(new OID(mibStr)));
		pdu.setType(PDU.GET);
		snmp.send(pdu, target, null, listener);
	}

	public void callback(String key, HashMap<String, String> mibRes) {
		this.result.put(key, mibRes);
	}
}
